package org.example.rabbitmq.product.config.rabbitmq;

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author hzq
 * @date 2021/11/24 14:18
 */
@Configuration
public class RabbitmqQueueConfiguration {

    /**
     * 队列参数作用
     * String name, 队列的名称-不能为null;设置为"",以便让代理生成名称。
     * boolean durable, 如果我们声明一个持久队列(队列将在服务器重启后继续存在),则为True
     * boolean exclusive, 如果我们声明了一个独占队列(该队列只会被声明者的连接使用),则为True
     * boolean autoDelete, 如果服务器应该在队列不再使用时删除该队列,则为True
     *
     * @Nullable Map<String, Object> arguments 用于声明队列的参数
     */

    @Bean
    public Queue directQueueOne() {
        return new Queue("queue.direct.one");
    }

    @Bean
    public Queue twoQueueDirect() {
        return new Queue("two.queue.direct", true);
    }

    @Bean
    public Queue queueFanoutOne() {
        return new Queue("queue.fanout.one", true, false, false);
    }

    @Bean
    public Queue fanoutQueueTwo() {
        return new Queue("fanout.queue.two", true, false, false, null);
    }

    @Bean
    public Queue oneQueueTopic() {
        return new Queue("one.queue.topic");
    }

    @Bean
    public Queue topicQueueTwo() {
        return new Queue("topic.queue.two");
    }

    /**
     * 延时队列
     */
    @Bean
    public Queue delayQueue() {
        Map<String, Object> arguments = new HashMap<>();
        /*
            Message在队列中可以存活多长时间，以毫秒为单位。
            发布的消息在queue时间超过了你设定的时间就会被删除掉。
         */
        arguments.put("x-message-ttl", 60000);/*设置queue的消息过期时间为60秒*/
        /*
            设置当前的queue在指定的时间内，
            没有consumer、basic.get也就是未被访问，就会被删除。
         */
//        arguments.put("x-expires", 30000);/*声明一个queue，queue60秒内而且未被任何形式的消费,则被删除*/
        arguments.put("x-max-length", 5);/*queue中可以存储处于ready状态的消息数量*/
        arguments.put("x-max-length-bytes", 1024);/*队列中可以存储处于ready状态消息占用内存的大小(只计算消息体的字节数，不计算消息头、消息属性占用的字节数)*/
        /*
            就像上面的message-ttl、max-length等。
            消息因为超时或超过限制在队列里消失，这样我们就丢失了一些消息，也许里面就有一些是我们做需要获知的。
            而rabbitmq的死信功能则为我们带来了解决方案。设置了dead-letter-exchange与dead-letter-routing-Key（要么都设定，要么都不设定）
            那些因为超时或超出限制而被删除的消息会被推动到我们设置的exchange中，再根据 routing key 推到queue中
         */
        arguments.put("x-dead-letter-exchange", "topic.mode");/*死信交换器名称*/
        arguments.put("x-dead-letter-routing-key", "topic.queue.*");/*死信路由键*/

        return new Queue("delay.queue", true, false, false, arguments);
    }

    /**
     * 自定义延时队列
     */
//    @Bean
//    public Queue customDelayQueue() {
//        return QueueBuilder.durable("custom.delay.queue")
//                .withArgument("x-message-ttl", 120000)
//                .withArgument("x-dead-letter-exchange", "topic.mode")
//                .withArgument("x-dead-letter-routing-key", "*.queue.topic")
//                .build();
//    }

}
